package com.nut.article.interceptor;

import com.nut.article.util.JacksonUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;

/**
 * 请求参数，出参，方法耗时等日志统计
 */
@Aspect
@Component
@Slf4j
public class ApiLogAspect {

    /**
     * controller切入点
     */
    @Pointcut("execution(public * com.nut.article.api.biz.*.*(..)))")
    public void controllerAspect() {
    }

    @Around("controllerAspect()")
    public Object doControllerAround(ProceedingJoinPoint jp) throws Throwable {
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        long beginTime = System.currentTimeMillis();
        StringBuilder sb = new StringBuilder();
        // 打印请求内容
        sb.append("\nrequest_ip=").append(request.getRemoteAddr())
                .append("\nrequest_url=").append(request.getRequestURL().toString())
                .append("\nrequest=").append(request.getMethod())
                .append("\nrequest_method=").append(jp.getSignature())
                .append("\nrequest_args=").append(Arrays.toString(jp.getArgs()));
        log.info(sb.toString());

        Object result = jp.proceed();
        long endTime = System.currentTimeMillis();

        // 取消二维码打印
        if (jp.getSignature().toString().contains("qrCode")) {
            return result;
        }

        sb = new StringBuilder();
        sb.append("\nresponse_time=").append(endTime - beginTime)
                .append("\nresponse_content=").append(JacksonUtils.toJson(result));
        log.info(sb.toString());
        return result;
    }

}
